package framework.states;

import java.util.ArrayList;

import org.newdawn.slick.AngelCodeFont;
import org.newdawn.slick.Color;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Input;
import org.newdawn.slick.Music;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.Sound;
import org.newdawn.slick.state.GameState;
import org.newdawn.slick.state.StateBasedGame;
import org.newdawn.slick.state.transition.FadeInTransition;
import org.newdawn.slick.state.transition.FadeOutTransition;

import framework.C;

public class Menu extends WelcomeScreen {

	public static final int ID = 2;
	/** if the user selected an item */
	protected boolean selected;
	/** the menu item to highlight */
	protected int currentItem;
	/** */
	protected ArrayList<MenuItem> states;
	/** */
	protected Sound sound;
	/** */
	protected Music explosionSound;
	/** the menu item to highlight */
	protected AngelCodeFont font;
	
	protected AngelCodeFont hoverFont;

	public Menu() {
		selected = false;
		currentItem = -1;
		states = new ArrayList<MenuItem>();
	}

	@Override
	public void init(GameContainer gc, StateBasedGame game)
			throws SlickException {
		super.init(gc, game);
		this.sound = new Sound(C.ASSETS_FOLDER + "sounds.ogg");
		this.explosionSound = new Music(C.ASSETS_FOLDER + "select.ogg");
		font = new AngelCodeFont(C.FONTS_FOLDER + "menu.fnt", C.FONTS_FOLDER + "/menu.png");
		hoverFont = new AngelCodeFont(C.FONTS_FOLDER + "menu_hover.fnt", C.FONTS_FOLDER + "/menu_hover.png");
		setPreviousState(null);
	}
	
	@Override
	public void enter(GameContainer gc, StateBasedGame game) 
			throws SlickException {
		super.enter(gc, game);
		this.selected = false;	
	}

	@Override
	public void render(GameContainer gc, StateBasedGame game, Graphics g)
			throws SlickException {
		super.render(gc, game, g);
		int fontWidth;
		int fontHeight;
		for (int i=0; i < states.size(); i++) {
			MenuItem item = states.get(i);
			fontWidth = font.getWidth(item.getName());
			fontHeight = font.getHeight("Options");
			g.setFont(font);
			if (i == this.currentItem) {
				g.setFont(hoverFont);
			} 
			g.drawString(item.getName(), gc.getWidth() / 2 - fontWidth / 2, (i + 1) * fontHeight + gc.getHeight() / 1.75f);
			g.setColor(Color.white);
		}
	}

	@Override
	public void update(GameContainer gc, StateBasedGame game, int delta)
			throws SlickException {
		super.update(gc, game, delta);
		if (selected) {
			this.sound.stop();
			//this.explosionSound.stop();
			//this.explosionSound.play();
			if (states.get(currentItem).getState() instanceof Menu) {
				game.enterState(states.get(currentItem).getState().getID());
			} else {
				game.enterState(states.get(currentItem).getState().getID(), 
				        new FadeOutTransition(), new FadeInTransition());
			}
		}
	}

	@Override
	public int getID() {
		return ID;
	}

	@Override
	public void controllerButtonPressed(int controller, int button) {
		super.controllerButtonPressed(controller, button);
		selected = button == 1;
	}

	@Override
	public void controllerUpPressed(int controller) {
		this.currentItem = (this.currentItem - 1 < 0) ? 
				this.states.size() - 1 : this.currentItem - 1;
		this.sound.stop();
		this.sound.play();
	}

	@Override
	public void controllerDownPressed(int controller) {
		this.currentItem = (this.currentItem + 1 > this.states.size() - 1) ? 
				0 : this.currentItem + 1;
		this.sound.stop();
		this.sound.play();
	}

	@Override
	public void keyPressed(int button, char c) {
		super.keyPressed(button, c);
		if (Input.KEY_UP == button) {
			controllerUpPressed(0);
		} else if (Input.KEY_DOWN == button) {
			controllerDownPressed(0);
		} else if (Input.KEY_ENTER == button || Input.KEY_SPACE == button) {
			controllerButtonPressed(0, 1);
		}
	}

	public void addItem(String name, GameState state) {
		if (this.currentItem == -1)  {
			this.currentItem++;
		}
		states.add(new MenuItem(name, state));
	}
}
